home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / blue-2.2 / blue.tar / blue.c.orig < prev    next >
Text File  |  1989-10-22  |  8KB  |  375 lines

  1. /*****************************************************************************
  2.  *                                                                           *
  3.  *                         B l u e   M o o n                                 *
  4.  *                         =================                                 *
  5.  *                                                                           *
  6.  *                  A patience game by T.A.Lister                            *
  7.  *                                                                           *
  8.  *****************************************************************************/
  9.  
  10. /* #include <stdio.h>   made redundant by "curses". tal */
  11.  
  12. #include <signal.h>
  13. #include <curses.h>
  14.  
  15. long time();
  16.  
  17. #define NOCARD        -1
  18.  
  19. #define HEARTS        0
  20. #define SPADES        1
  21. #define DIAMONDS    2
  22. #define CLUBS        3
  23.  
  24. #define ACE        0
  25. #define TWO        1
  26. #define THREE        2
  27. #define FOUR        3
  28. #define FIVE        4
  29. #define SIX        5
  30. #define SEVEN        6
  31. #define EIGHT        7
  32. #define NINE        8
  33. #define TEN        9
  34. #define JACK        10
  35. #define QUEEN        11
  36. #define KING        12
  37.  
  38. #define SUIT_LENGTH    13
  39.  
  40. #define GRID_WIDTH    14    /*    13+1  */
  41. #define GRID_LENGTH    56    /* 4*(13+1) */
  42.  
  43. #define PACK_SIZE    52
  44.  
  45. int deck_size=PACK_SIZE;    /* initial deck */
  46. int deck[PACK_SIZE];
  47.  
  48. int grid[GRID_LENGTH];    /* card layout grid */
  49. int freeptr[4];        /* free card space pointers */
  50.  
  51. int deal_number=0;
  52.  
  53. die()
  54. {
  55.     signal(SIGINT, SIG_IGN);
  56.     mvcur(0, COLS-1, LINES-1, 0);
  57.     endwin();
  58.     exit(0);
  59. }
  60.  
  61. init_vars()
  62. {
  63.     int i;
  64.  
  65.     deck_size=PACK_SIZE;
  66.     for(i=0;i<PACK_SIZE;i++)    deck[i]=i;
  67.     for(i=0;i<4;i++)        freeptr[i]=i * GRID_WIDTH;
  68. }
  69.  
  70. instructions()
  71. {
  72.     char c;
  73.  
  74.     clear();
  75.     printw("Welcome to Blue Moon - do you want instructions? (y/n) : ");
  76.     refresh();
  77.     if(((c=getchar())=='n')||(c=='N'))    return;
  78.     clear();
  79.     printw("  Blue Moon is a solitaire or patience game played with a full 52 card deck.\n");
  80.     printw("  After shuffling the deck thoroughly, deal the entire deck out face up,\n");
  81.     printw("into four rows of 13 cards.  Find the Aces and move them to the left end of the\n");
  82.     printw("layout, so that each row begins with an Ace, reading Hearts, Spades, Diamonds\n");
  83.     printw("and Clubs from top to bottom.\n");
  84.     printw("  Now play may proceed.  You may move cards into the empty spaces, subject to\n");
  85.     printw("the proviso that you may only move into any space the card that is exactly one\n");
  86.     printw("higher in rank, and of the same suit, as the card to the left of the space.\n");
  87.     printw("  As Aces are low, Kings are high, and may not have any card moved into a space\n");
  88.     printw("to their right.  Thus spaces to the right of Kings are considered to be dead.\n");
  89.     printw("  Your aim is to end up with the four rows reading Ace to King in sequence.\n");
  90.     printw("  Since it is virtually impossible to get this out in one deal, this is not a\n");
  91.     printw("requirement of the game.  Instead, at the end of the play, leaving those cards\n");
  92.     printw("that are in sequence from an Ace alone, gather up the rest of the cards and\n");
  93.     printw("reshuffle them.  Deal the shuffled cards face up after the ends of the partial\n");
  94.     printw("sequences, leaving a card space after each sequence, so that each row reads\n");
  95.     printw("'A partial sequence', 'A space', 'enough cards to make a row of 14',\n");
  96.     printw("then proceed to play as before.  Repeat as often as necessary.  A moment's\n");
  97.     printw("reflection will show you that this game cannot take more than 13 deals.\n");
  98.     printw("  A good score is 1 to 3 deals, 4 to 7 is average, 8 or more is poor.\n");
  99.     printw("\n.....oooooOOOOO press <SPACE> to continue OOOOOooooo.....");
  100.     refresh();
  101.     (void) getchar();
  102. }
  103.  
  104. shuffle(size)
  105. int size;
  106. {
  107.     int i,j,numswaps,swapnum,temp;
  108.  
  109.     numswaps=size*10;    /* an arbitrary figure */
  110.  
  111.     for (swapnum=0;swapnum<numswaps;swapnum++)
  112.     {
  113.         i=rand() % size;
  114.         j=rand() % size;
  115.         temp=deck[i];
  116.         deck[i]=deck[j];
  117.         deck[j]=temp;
  118.     }
  119. }
  120.  
  121. deal_cards()
  122. {
  123.     int ptr, card=0, value, csuit, crank, suit, aces[4];
  124.  
  125.     for (suit=HEARTS;suit<=CLUBS;suit++)
  126.     {
  127.         ptr=freeptr[suit];
  128.         grid[ptr++]=NOCARD;    /* 1st card space is blank */
  129.         while ((ptr % GRID_WIDTH) != 0)
  130.         {
  131.             value=deck[card++];
  132.             crank=value % SUIT_LENGTH;
  133.             csuit=value / SUIT_LENGTH;
  134.             if (crank==ACE)
  135.                 aces[csuit]=ptr;
  136.             grid[ptr++]=value;
  137.         }
  138.     }
  139.  
  140.     if (deal_number==1)    /* shift the aces down to the 1st column */
  141.         for (suit=HEARTS;suit<=CLUBS;suit++)
  142.         {
  143.             grid[suit * GRID_WIDTH] = suit * SUIT_LENGTH;
  144.             grid[aces[suit]]=NOCARD;
  145.             freeptr[suit]=aces[suit];
  146.         }
  147. }
  148.  
  149. char suitch(suit)
  150. int suit;
  151. {
  152.     switch (suit)
  153.     {
  154.         case HEARTS:    return 'h';
  155.         case SPADES:    return 's';
  156.         case DIAMONDS:    return 'd';
  157.         case CLUBS:    return 'c';
  158.         default:    return '?';
  159.     }
  160. }
  161.  
  162. printcard(value)
  163. int value;
  164. {
  165.     int rank, suit;
  166.  
  167.     rank=value % SUIT_LENGTH;
  168.     suit=value / SUIT_LENGTH;
  169.     switch (rank)
  170.     {
  171.         case NOCARD:    printw(" [ ] ");
  172.                 break;
  173.  
  174.         case ACE:    printw("  A%c ",suitch(suit));
  175.                 break;
  176.  
  177.         default: /* TWO to TEN */
  178.                 printw(" %2d%c ",rank+1,suitch(suit));
  179.                 break;
  180.  
  181.         case JACK:    printw("  J%c ",suitch(suit));
  182.                 break;
  183.  
  184.         case QUEEN:    printw("  Q%c ",suitch(suit));
  185.                 break;
  186.  
  187.         case KING:    printw("  K%c ",suitch(suit));
  188.                 break;
  189.     }
  190. }
  191.  
  192. display_cards(deal)
  193. int deal;
  194. {
  195.     int row, card;
  196.  
  197.     clear();
  198.     printw("Blue Moon - by Tim Lister - Deal Number %d.\n\n",deal);
  199.     for(row=HEARTS;row<=CLUBS;row++)
  200.     {
  201.         move(row+row+2, 0);
  202.         for(card=0;card<GRID_WIDTH;card++)
  203.             printcard(grid[row * GRID_WIDTH + card]);
  204.     }
  205.     refresh();
  206. }
  207.  
  208. find(card)
  209. int card;
  210. {
  211.     int i;
  212.  
  213.     if ((card<0)||(card>=PACK_SIZE))    return NOCARD;
  214.     for(i=0;i<GRID_LENGTH;i++)
  215.         if (grid[i]==card)        return i;
  216.     return NOCARD;
  217. }
  218.  
  219. movecard(src, dst)
  220. int src, dst;
  221. {
  222.     grid[dst]=grid[src];
  223.     grid[src]=NOCARD;
  224.  
  225.     move( (dst / GRID_WIDTH)*2+2, (dst % GRID_WIDTH)*5);
  226.     printcard(grid[dst]);
  227.  
  228.     move( (src / GRID_WIDTH)*2+2, (src % GRID_WIDTH)*5);
  229.     printcard(grid[src]);
  230.  
  231.     refresh();
  232. }
  233.  
  234. play_game()
  235. {
  236.     int dead=0, i, j;
  237.     char c;
  238.     int select[4], card;
  239.  
  240.     while (dead<4)
  241.     {
  242.         dead=0;
  243.         for (i=0;i<4;i++)
  244.         {
  245.             card=grid[freeptr[i]-1];
  246.  
  247.             if (    ((card % SUIT_LENGTH)==KING)
  248.                 ||
  249.                 (card==NOCARD)    )
  250.                 select[i]=NOCARD;
  251.             else
  252.                 select[i]=find(card+1);
  253.  
  254.             if (select[i]==NOCARD)
  255.                 dead++;
  256.         };
  257.  
  258.         if (dead<4)
  259.         {
  260.             for (i=0;i<4;i++)
  261.             {
  262.                 move(12+i,0);
  263.                 printw("%c:  ",'a'+i);
  264.                 if (select[i]==NOCARD)
  265.                     printw("DEAD ");
  266.                 else
  267.                 {
  268.                     printcard(grid[select[i]]);
  269.                     move( (select[i] / GRID_WIDTH)*2+3,
  270.                           (select[i] % GRID_WIDTH)*5);
  271.                     printw("  ^  ");
  272.                 }
  273.             };
  274.  
  275.             move(18,0);
  276.             printw("Select undead card to move (a..d), R to redraw, RUBOUT to quit : ");
  277.             refresh();
  278.             for (j=0;j<4;j++)
  279.                 if (select[j]!=NOCARD)
  280.                 {
  281.                     move( (select[j] / GRID_WIDTH)*2+3,
  282.                           (select[j] % GRID_WIDTH)*5);
  283.                     printw("     ");
  284.                 }
  285.  
  286.             while ((((c=getchar())<'a')||(c>'d'))&&(c!='r')&&(c!='R'));
  287.             if ((c=='r')||(c=='R'))
  288.                 wrefresh(curscr);
  289.             else
  290.             {
  291.                 i=c-'a';
  292.                 if (select[i]!=NOCARD)
  293.                 {
  294.                     movecard(select[i], freeptr[i]);
  295.                     freeptr[i]=select[i];
  296.                 }
  297.             }
  298.         }
  299.     }
  300.     for (i=0;i<4;i++)
  301.     {
  302.         move(12+i,0);
  303.         printw("%c:  ",'a'+i);
  304.         printw("DEAD ");
  305.     }
  306.     move(20,0);
  307.     printw(".....oooooOOOOO Finished Deal %d - Press <SPACE> to Continue OOOOOooooo.....", deal_number);
  308.     refresh();
  309.     (void) getchar();
  310. }
  311.  
  312. collect_discards()
  313. {
  314.     int row, col, cardno=0, finish, gridno;
  315.  
  316.     for (row=HEARTS;row<=CLUBS;row++)
  317.     {
  318.         finish=0;
  319.         for (col=1;col<GRID_WIDTH;col++)
  320.         {
  321.             gridno=row * GRID_WIDTH + col;
  322.  
  323.             if ((grid[gridno]!=(grid[gridno-1]+1))&&(finish==0))
  324.             {
  325.                 finish=1;
  326.                 freeptr[row]=gridno;
  327.             };
  328.  
  329.             if ((finish!=0)&&(grid[gridno]!=NOCARD))
  330.                 deck[cardno++]=grid[gridno];
  331.         }
  332.     }
  333.     return cardno;
  334. }
  335.  
  336. game_finished(deal)
  337. int deal;
  338. {
  339.     clear();
  340.     printw("\n\n\nYou finished the game in %d deals.\nThis is ",deal);
  341.     if (deal<4)
  342.         printw("good.\n");
  343.     else if (deal<8)
  344.         printw("average.\n");
  345.     else
  346.         printw("poor.\n");
  347.     refresh();
  348.     die();
  349. }
  350.  
  351. main()
  352. {
  353.     initscr();
  354.     signal(SIGINT, die);
  355.     crmode();
  356.     noecho();
  357.     scrollok(stdscr, FALSE);
  358.  
  359.     instructions();
  360.  
  361.     srand((int)time((long *)0));
  362.  
  363.     init_vars();
  364.  
  365.     do{
  366.         deal_number++;
  367.         shuffle(deck_size);
  368.         deal_cards();
  369.         display_cards(deal_number);
  370.         play_game();
  371.     }while    ((deck_size=collect_discards()) != 0);
  372.  
  373.     game_finished(deal_number);
  374. }
  375.